package cbbx_sm.utils;

import java.applet.Applet;
import java.awt.Graphics;
 
public class HilbertCurve extends Applet {
	
    private SimpleGraphics sg=null;
    private int dist0=800, dist=dist0;
 
    public void init( ) {
        resize ( dist0, dist0 );
        sg = new SimpleGraphics(getGraphics());
    }
 
    public void paint(Graphics g) {
        int level = 7;
        dist = dist0;
        for (int i=level; i>0; i--) dist /= 2;
        sg.goToXY ( dist/2, dist/2 );
        HilbertU(level); // start recursion
    }
 
    // Make U-shaped curve at this scale:
    private void HilbertU(int level) {
        if (level > 0) {
            HilbertD(level-1);    sg.lineRel(0, dist);
            HilbertU(level-1);    sg.lineRel(dist, 0);
            HilbertU(level-1);    sg.lineRel(0, -dist);
            HilbertC(level-1);
        }
    }
 
    // Make D-shaped (really "]" shaped) curve at this scale:
    private void HilbertD(int level) {
        if (level > 0) {
            HilbertU(level-1);    sg.lineRel(dist, 0);
            HilbertD(level-1);    sg.lineRel(0, dist);
            HilbertD(level-1);    sg.lineRel(-dist, 0);
            HilbertA(level-1);
        }
    }
 
    // Make C-shaped (really "[" shaped) curve at this scale:
    private void HilbertC(int level) {
        if (level > 0) {
            HilbertA(level-1);    sg.lineRel(-dist, 0);
            HilbertC(level-1);    sg.lineRel(0, -dist);
            HilbertC(level-1);    sg.lineRel(dist, 0);
            HilbertU(level-1);
        }
    }
 
    // Make A-shaped (really "?" shaped) curve at this scale:
    private void HilbertA(int level) {
        if (level > 0) {
            HilbertC(level-1); sg.lineRel(0, -dist);
            HilbertA(level-1); sg.lineRel(-dist, 0);
            HilbertA(level-1); sg.lineRel(0, dist);
            HilbertD(level-1);
        }
    }
}
 
class SimpleGraphics {
    private Graphics g = null;
    private int x = 0, y = 0, i=0;   
 
    public SimpleGraphics(Graphics g) { this.g = g; }
    public void goToXY(int x, int y) { this.x = x;   this.y = y; }
 
    public void lineRel(int deltaX, int deltaY) {
        g.drawLine ( x, y, x+deltaX, y+deltaY );
        //g.drawString(i+"", x, y);
        x += deltaX;    y += deltaY;
        System.out.println(i+") X = "+x+" Y="+y);
        i++;
    }
}
